<template>
	<view class="detail-share">
		<canvas class="canvas" canvas-id="canvas" :style="{ height: canvasHeight + 'px' }" />
		<image
			class="image"
			mode="widthFix" 
			v-if="tempFilePath"
			:src="tempFilePath"
			@error="finishLoadMainImage"
			@load="finishLoadMainImage"></image>
		<image
			mode="widthFix"
			v-show="false"
			v-for="(image, i) in defaultImages"
			:key="image"
			:src="image"
			@error="finishLoad($event, i)"
			@load="finishLoad($event, i)">
		</image>
	</view>
</template>

<script>
let timer;

export default {
	data() {
		return {
			padding: 28,
			shareType: 'save',
			defaultImages: [],
			imageBaseInfo: [],
			tempFilePath: null,
			detailData: {},
			canvasWidth: 350,
			canvasHeight: 350,
		};
	},
	onLoad({ type, canvasWidth, canvasHeight, id, data }) {
		uni.showLoading({ title: '图片绘制中...', mask: true });
		this.shareType = type || 'save';
		this.canvasWidth = canvasWidth || 350;
		this.canvasHeight = canvasHeight || 350;
		// this.detailData = data ? JSON.parse(decodeURIComponent(data)) : {};
		this.$nextTick(() => {
			this.getDetailData(id);
		});
	},
	onReady() {
	},
	methods: {
		getDetailData(id) {
			uni.$request({
				method: 'GET',
				url: 'app-api/homework/write/get',
				data: { id },
				header: { 'tenant-id': 1 },
			}).then((res) => {
				const data = res?.data || {};
				this.detailData = { ...data, ...(this.getTimesByTimeStamp(data.createTime) || {}) };
				this.downloadFile();
			}).catch(uni.hideLoading);
		},
		downloadFile() {
			const promises = (this.detailData?.attList || []).map(({ attachment }) => uni.downloadFile({ url: attachment }));
			if (!promises.length) {
				this.drawImageToTempFilePath();
				return;
			}
			Promise.all(promises).then((resArr) => {
				this.defaultImages = resArr.flat(2).filter(d => d).map(({ tempFilePath }) => tempFilePath);
			});
		},
		finishLoad(data, i) {
			const { width, height } = (data || {}).detail || {};
			this.imageBaseInfo[i] = {
				width: this.canvasWidth - (this.padding * 2),
				height: height ? (this.canvasWidth - (this.padding * 2)) * height / width : 300,
			};
			const canDraw = !this.imageBaseInfo.some(item => !item) && this.imageBaseInfo.length === this.defaultImages.length;
			if (canDraw) {
				clearTimeout(timer);
				timer = setTimeout(this.drawImageToTempFilePath, 200)
			}
		},
		finishLoadMainImage() {
			setTimeout(uni.hideLoading, 200);
		},
		drawImageToTempFilePath() {
			const _this = this;
			// uni.showLoading({ title: '图片绘制中...', mask: true });
			const ctx = uni.createCanvasContext('canvas');
			let currentY = 49;
			
			ctx.font = '20px HarmonyOS Sans SC-Regular, HarmonyOS Sans SC';
			ctx.setFillStyle('#333333');
			currentY = this.canvasTextAutoLine(ctx, this.detailData.title || '主标题', this.padding, currentY, this.canvasWidth - (this.padding * 2), 25);
			
			ctx.setFontSize(12);
			ctx.setFillStyle('#ABB3BB');
			ctx.fillText(this.detailData.dateTime || '时间', this.padding, currentY);
			
			ctx.setFontSize(14);
			ctx.setFillStyle('#333333');
			currentY += 28;
			currentY = this.canvasTextAutoLine(ctx, this.detailData.content || '正文', this.padding, currentY, this.canvasWidth - (this.padding * 2), 23);
			
			this.defaultImages.forEach((image, i) => {
				const { width = this.canvasWidth - (this.padding * 2), height = 300 } = this.imageBaseInfo[i] || {};
				ctx.drawImage(image, this.padding, currentY, width, height);
				currentY += (height + 4);
			});
			
			ctx.fill();
			
			ctx.draw(true, () => {
				setTimeout(() => {
					uni.canvasToTempFilePath({
						fileType: 'jpg',
						canvasId: 'canvas',
						success(res) {
							_this.tempFilePath = res.tempFilePath;
							_this[({
								share: 'shareImage',
								save: 'saveImageToPhotosAlbum',
							})[_this.shareType]]();
						},
						fail() {
							uni.showModal({
								title: '提示',
								content: '图片绘制失败，请稍后重试！',
								confirmText: '好的',
								showCancel: false,
							});
							uni.hideLoading();
						},
					}, _this);
				}, 300);
			});
		},
		canvasTextAutoLine(ctx, text, x, y, maxWidth, lineHeight) {
			let lineWidth = 0;
			let lastSubStrIndex = 0;
			// wrap(换行) overlength(长度超过) leftover(剩余部分)
			let lastLineType;
			for (let i = 0; i < text.length; i++) {
				lineWidth += ctx.measureText(text[i]).width;
				if (text[i] === '\n') {
					ctx.fillText(text.substring(lastSubStrIndex, i).replace(/\n/ig, ''), x, y);
					y += lineHeight;
					lineWidth = 0;
					lastSubStrIndex = i;
					lastLineType = 'wrap';
				} else if (lineWidth > maxWidth) {
					ctx.fillText(text.substring(lastSubStrIndex, i).replace(/\n/ig, ''), x, y);
					y += lineHeight;
					lineWidth = 0;
					lastSubStrIndex = i;
					lastLineType = 'overlength';
				} else if (i === text.length - 1) {
					ctx.fillText(text.substring(lastSubStrIndex, text.length).replace(/\n/ig, ''), x, y);
					y += lineHeight;
					lastLineType = 'leftover';
				}
			}
			return y;
		},
		saveImage() {
			uni.saveImageToPhotosAlbum({
				filePath: this.tempFilePath,
				success() {
					uni.showToast({ title: '已保存至相册' });
				},
				fail(err) {
					uni.showToast({ title: '图片保存失败', icon: 'none' });
				},
			});
		},
		// 保存到相册
		saveImageToPhotosAlbum() {
			const _this = this;
			if (!uni.getSetting) return;
			uni.getSetting({
				success(res) {
					if (res.authSetting['scope.writePhotosAlbum']) {
						_this.saveImage();
						return;
					}
					uni.authorize({
						scope: 'scope.writePhotosAlbum',
						success() {
							_this.saveImage();
						},
						fail() {
							uni.showModal({
								title: '提示',
								content: '未授权，保存失败！',
								confirmText: '好的',
								showCancel: false,
							});
						},
					});
				},
			});
		},
		// 分享给朋友
		shareImage() {
			if (wx && wx.showShareImageMenu) {
				wx.showShareImageMenu({ path: this.tempFilePath });
			}
		},
		getTimesByTimeStamp(timeStamp) {
		   const date = new Date(timeStamp);
		   const format = s => `0${s || 0}`.slice(-2);
		   const year = date.getFullYear();
		   const month = format(date.getMonth() + 1);
		   const day = format(date.getDate());
		   const weekday = ({
			   0: '周日',
			   1: '周一',
			   2: '周二',
			   3: '周三',
			   4: '周四',
			   5: '周五',
			   6: '周六',
		   })[date.getDay()];
		   const time = `${format(date.getHours())}:${format(date.getMinutes())}`;
		   const dateTime = `${year}-${month}-${day} ${weekday} ${time}`;
		   return { year, month, day, weekday, time, dateTime };
		},
	}
};
</script>

<style lang="scss">
	.detail-share {
		padding-bottom: 50rpx;
		background: black;
		height: 100vh;
		box-sizing: border-box;
		overflow-y: auto;
		.canvas {
			width: 100vw;
			min-height: 100vh;
			position: absolute;
			z-index: -1;
			opacity: 0;
			top: -99999rpx;
		}
		.image {
			width: calc(100% - 80rpx);
			margin: 40rpx;
		}
	}
</style>
